home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World Komputer 2010 April
/
PCWorld0410.iso
/
pluginy Firefox
/
398
/
398.xpi
/
chrome
/
forecastfox.jar
/
content
/
ping
/
ping-service.js
next >
Wrap
Text File
|
2010-02-04
|
11KB
|
363 lines
/*------------------------------------------------------------------------------
Copyright (c) 2008 Ensolis, LLC. All Rights Reserved.
----------------------------------------------------------------------------*/
/******************************************************************************
* Ping Constants
*****************************************************************************/
const RUN_INSTALL = Ci.ffIPingService.RUN_INSTALL;
const RUN_UPGRADE = Ci.ffIPingService.RUN_UPGRADE;
const RUN_UNINSTALL = Ci.ffIPingService.RUN_UNINSTALL;
/******************************************************************************
* Interfaces used monitor upgrade, install, uninstall process and
* notify the server when changes occur.
*
* @status FROZEN
* @version 1.0
******************************************************************************/
function PingService()
{
//setup additional interfaces
this._ifaces.push(Ci.nsIObserver);
this._ifaces.push(Ci.nsISupportsWeakReference);
//setup a new error
this._error = Cc["@ensolis.com/forecastfox/error-item;1"].
createInstance(Ci.ffIErrorItem);
}
PingService.prototype = {
__proto__: new ServiceBase("PingService"),
_obSvc: null,
_checkTimer: null,
////////////////////////////
// nsIObserver
observe: function PingService_observe(aSubject, aTopic, aData)
{
// check the interval on timer callback
if (aTopic == "timer-callback") {
this._checkInterval();
return;
}
//only do something if item is us
var item = aSubject.QueryInterface(Ci.nsIUpdateItem);
if (item.id != "{0538E3E3-7E9B-4d49-8831-A227C80A7AD3}")
return;
//get the migrator service
var mgrSvc = Cc["@ensolis.com/forecastfox/manager-service;1"].
getService(Ci.ffIManagerService);
var migSvc = mgrSvc.migrator;
//determine action based on message
switch (aData) {
//being upgraded
case "item-upgraded":
//going to version less than tracked
if (migSvc.compare(item.version, "0.7") < 0)
this._send(RUN_UNINSTALL, "0.9.10", "*");
break;
//being uninstalled
case "item-uninstalled":
this._send(RUN_UNINSTALL, "0.9.10", "*");
break;
//being cancelled
case "item-cancel-action":
this.run();
break;
}
},
////////////////////////////////
// ffIService
/**
* Initialize the component. Called by the manager service.
*/
start: function PingService_start()
{
//get extension manager
var exMgr = Cc["@mozilla.org/extensions/manager;1"].
getService(Ci.nsIExtensionManager);
// do our ping tracking
this._checkInterval();
// start the check timer
this._checkTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
this._checkTimer.init(this, 10*ONE_MINUTE, Ci.nsITimer.TYPE_REPEATING_SLACK);
//add observer
this._obSvc = Cc["@mozilla.org/observer-service;1"].
getService(Ci.nsIObserverService);
this._obSvc.addObserver(this, "em-action-requested", false);
//return success
return true;
},
/**
* Destroy the component. Called by the manager service. This may be
* called prior to start so it needs to be safe.
*/
stop: function PingService_stop()
{
//unregister from the observer service
this._obSvc.removeObserver(this, "em-action-requested");
// stop the check timer
this._checkTimer.cancel();
this._checkInterval();
//remove image references
for (id in AccuTrack.images) {
image = AccuTrack.images[id];
image.onload = null;
image.parentNode.removeChild(image);
delete AccuTrack.images[id];
}
//remove variables
this._obSvc = null;
this._checkTimer = null;
},
////////////////////////////////
// ffIPingService
/**
* Run ping command.
*/
run: function PingService_run()
{
//get preferences
var pinged = getPref("pinged");
var migrated = getPref("migrated");
//use migrated value if pinged is blank
if (pinged == "" && migrated != "")
pinged = migrated;
//determine ping command and send
switch (pinged) {
//same version do nothing
case "0.9.10":
break;
//never installed or previously uninstalled.
case "":
case "*":
this._send(RUN_INSTALL, "", "0.9.10");
break;
//upgrading from old version
default:
this._send(RUN_UPGRADE, pinged, "0.9.10");
break;
}
},
/**
* Function for tracking ui events. This method has the same signature as
* the Google Analytics Event Tracking. This allows us to implement that
* functionality in the future if we need it.
*
* @param The category of the event.
* @param The action to track.
* @param Optional label for the event.
* @param Optional value for the event.
*/
trackEvent: function PingService_trackEvent(category, action, label, value) {
// pass on to accuweather gif tracking
AccuTrack.push(category, action, label, value);
// any other type of tracking
},
/**
* Pass a url to our internal trackers where the only thing that needs
* updates is the random value in the url.
*
* @param The url to track.
*/
trackURL: function PingService_trackURL(url) {
// pass on to accuweather gif tracking
AccuTrack.url(url);
// any other type of tracking
},
////////////////////////////
// Internal Functions
/**
* Build query string and send request.
*
* @param Type of ping command to perform.
* @param Version we are coming from.
* @param Version we are going to.
*/
_send: function PingService__send(aType, aFrom, aTo)
{
//create query url
var query = "http://forecastfox.ensolis.com/logs/log.php";
var guid = "{ec8030f7-c20a-464f-9b0e-13a3a9e97384}";
query += "?type=" + aType;
query += "&from=" + aFrom;
query += "&to=";
query += (aTo == "*") ? "" : aTo;
query += "&guid=" + guid;
//send ping request
var request = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].
createInstance(Ci.nsIXMLHttpRequest);
request.open("GET", query, true);
//update channel priority - toolkit 1.5 or greater
if ("nsISupportsPriority" in Ci) {
if (request.channel instanceof Ci.nsISupportsPriority)
request.channel.priority = Ci.nsISupportsPriority.PRIORITY_HIGHEST;
}
request.send(null);
//set pref as to version
setPref("pinged", aTo);
//log the ping in the errors.log for help debugging.
var mgrSvc = Cc["@ensolis.com/forecastfox/manager-service;1"].
getService(Ci.ffIManagerService);
var dskSvc = mgrSvc.disk;
switch (aType) {
case RUN_INSTALL:
dskSvc.log("Installing version " + aTo + " on " + guid, null, null);
break;
case RUN_UNINSTALL:
dskSvc.log("Uninstalling version " + aFrom + " on " + guid, null, null);
break;
case RUN_UPGRADE:
dskSvc.log("Upgrading version " + aFrom + " to " + aTo + " on " + guid,
null, null);
break;
}
},
_checkInterval: function PingService__checkInterval() {
var now = Math.round(Date.now() / 1000);
var daily = getPref("pinged.daily");
var weekly = getPref("pinged.weekly");
var monthly = getPref("pinged.monthly");
// do daily ping
if ((now - daily > ONE_DAY/1000) || (now - daily < 0)) {
this.trackEvent("active", "users", "daily");
setPref("pinged.daily", now);
}
// do weekly ping
if ((now - weekly > ONE_WEEK/1000) || (now - weekly < 0)) {
this.trackEvent("active", "users", "weekly");
setPref("pinged.weekly", now);
}
// do monthly ping
if ((now - monthly > ONE_MONTH/1000) || (now - monthly < 0)) {
this.trackEvent("active", "users", "monthly");
setPref("pinged.monthly", now);
}
}
};
/*******************************************************************************
* Object to do the gif based accuweather tracking. The push method is called
* from trackEvent with all the same parameters. We lowercase the params and
* join them with a "-". This is used as a key to lookup the image that needs
* loaded. A random id is generated and the image is stored via that id.
* On the image load event the pop method is called with the image id and it is
* removed from hash of stored images.
******************************************************************************/
var AccuTrack = {
images: {},
keys: {
"tooltip-load-swa": "QXA3515",
"tooltip-load-radar": "QXA3516",
"tooltip-load-cc": "QXA3517",
"tooltip-load-dayt": "QXA3518",
"tooltip-load-dayf": "QXA3519",
"tooltip-click-radar": "QXA3520",
"active-users-monthly": "QXA3521",
"active-users-weekly": "QXA3522",
"active-users-daily": "QXA3523"
},
push: function accutrack_push(category, action, label, value) {
var url_format="http://spotlight.accuweather.com/dyndoc/spotlight/adc_$key/index/flasher.gif?cbs=$id";
// determine the key
var parts = [category, action, label, value];
var key = parts.filter(function(a) { return (a) ? true : false; }).join("-");
// if the key doesn't exist return early
if (!this.keys.hasOwnProperty(key))
return;
// build the url
var id = (new Date()).getTime();
var url = url_format.replace("$key", this.keys[key]);
url = url.replace("$id", id);
LOG("forecastfox ping: " + url);
// setup the image and store it in the hash
var self = this;
this.images[id] = this._createImage();
this.images[id].onload = function() { self.pop(id); };
this.images[id].src = url;
},
pop: function accutrack_pop(id) {
if (!this.images.hasOwnProperty(id))
return;
var image = this.images[id];
image.onload = null;
image.parentNode.removeChild(image);
delete this.images[id];
},
url: function accutrack__url(url) {
// build the url
var id = (new Date()).getTime();
var new_url = url.replace("RANDOM", id);
LOG("forecastfox ping: " + new_url);
// setup the image and store it in the hash
var self = this;
this.images[id] = this._createImage();
this.images[id].onload = function() { self.pop(id); };
this.images[id].src = new_url;
},
_createImage: function accutrack__createImage() {
var main = getMainWindow();
var doc = main.document;
var image = doc.createElement("image");
image.setAttribute("collapsed", "true");
var root = doc.documentElement;
root.appendChild(image);
return image;
}
};